//
//  TTVWebServerManage.m
//  TouchTV-Report
//
//  Created by 周启睿 on 2019/5/6.
//  Copyright © 2019 周启睿. All rights reserved.
//

#import "TTVWebServerManage.h"
//#import <GCDWebServer/GCDWebServer.h>
//#import <GCDWebServer/GCDWebServerDataResponse.h>
//#import <GCDWebServer/GCDWebDAVServer.h>
//#import <GCDWebServer/GCDWebUploader.h>
#import "GCDWebServer.h"
#import "GCDWebServerDataResponse.h"
#import "GCDWebUploader.h"
#import "GCDWebDAVServer.h"


#define kMinRefreshDelay 99999


@interface TTVWebServerManage ()
<
GCDWebUploaderDelegate,
GCDWebServerDelegate
>
@property (nonatomic, strong) GCDWebServer *webServer;
@property (nonatomic, strong) GCDWebDAVServer *davServer;

@end

@implementation TTVWebServerManage

static TTVWebServerManage *_instance;

+ (id)allocWithZone:(struct _NSZone *)zone{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

+ (instancetype)WebServeManage{
    if (_instance == nil) {
        _instance = [[TTVWebServerManage alloc] init];
    }
    return _instance;
}

- (instancetype)init{
    self = [super init];
    if (self) {
        [self setup];
    }
    return self;
}

#pragma mark - web服务配置
- (void)setup{
    
    
    //WebDAV
    NSString* documentsPath = NSHomeDirectory();
    GCDWebDAVServer* davServer = [[GCDWebDAVServer alloc] initWithUploadDirectory:documentsPath];
    _davServer = davServer;
    [self.davServer startWithPort:9091 bonjourName:nil];
    
    //webServer
    GCDWebServer* webServer = [[GCDWebServer alloc] init];
    _webServer = webServer;
    __weak __typeof(self)weakSelf = self;
    if ([self.webServer isKindOfClass:GCDWebServer.class]) {
        [self.webServer addDefaultHandlerForMethod:@"GET"
                                  requestClass:[GCDWebServerRequest class]
                                  processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
                                      return [GCDWebServerDataResponse responseWithHTML:@"<html><body><p>Hello World</p></body></html>"];
                                  }];


        [self.webServer addHandlerForMethod:@"GET" path:@"/log" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse * _Nullable(__kindof GCDWebServerRequest * _Nonnull request) {
            NSString* logHtmlContent = [weakSelf logHtmlContent];
            return [weakSelf createResponseBody:request htmlContent:logHtmlContent];
        }];
    }
    else if ([self.webServer isKindOfClass:GCDWebDAVServer.class]) {
    }
    else if ([self.webServer isKindOfClass:GCDWebUploader.class]) {
    }
    [self.webServer startWithPort:9090 bonjourName:nil];
}


#pragma mark - 返回封装
//当浏览器请求的时候,返回一个由日志信息组装成的html返回给浏览器
- (GCDWebServerDataResponse *)createResponseBody :(GCDWebServerRequest* )request htmlContent:(NSString*)htmlContent{
    GCDWebServerDataResponse *response = nil;
    
    NSString* path = @"/";//request.path;
    NSDictionary* query = request.query;
    //NSLog(@"path = %@,query = %@",path,query);
    NSMutableString* string;
    if ([path isEqualToString:@"/"]) {
        string = [[NSMutableString alloc] init];
        [string appendString:@"<!DOCTYPE html><html lang=\"en\">"];
        [string appendString:@"<head><meta charset=\"utf-8\"></head>"];
        [string appendFormat:@"<title>%s[%i]</title>", getprogname(), getpid()];
        [string appendString:@"<style>\
         body {\n\
         margin: 0px;\n\
         font-family: Courier, monospace;\n\
         font-size: 0.8em;\n\
         }\n\
         table {\n\
         width: 100%;\n\
         border-collapse: collapse;\n\
         }\n\
         tr {\n\
         vertical-align: top;\n\
         }\n\
         tr:nth-child(odd) {\n\
         background-color: #eeeeee;\n\
         }\n\
         td {\n\
         padding: 2px 10px;\n\
         }\n\
         #footer {\n\
         text-align: center;\n\
         margin: 20px 0px;\n\
         color: darkgray;\n\
         }\n\
         .error {\n\
         color: red;\n\
         font-weight: bold;\n\
         }\n\
         </style>"];
        [string appendFormat:@"<script type=\"text/javascript\">\n\
         var refreshDelay = %i;\n\
         var footerElement = null;\n\
         function updateTimestamp() {\n\
         var now = new Date();\n\
         footerElement.innerHTML = \"Last updated on \" + now.toLocaleDateString() + \" \" + now.toLocaleTimeString();\n\
         }\n\
         function refresh() {\n\
         var timeElement = document.getElementById(\"maxTime\");\n\
         var maxTime = timeElement.getAttribute(\"data-value\");\n\
         timeElement.parentNode.removeChild(timeElement);\n\
         \n\
         var xmlhttp = new XMLHttpRequest();\n\
         xmlhttp.onreadystatechange = function() {\n\
         if (xmlhttp.readyState == 4) {\n\
         if (xmlhttp.status == 200) {\n\
         var contentElement = document.getElementById(\"content\");\n\
         contentElement.innerHTML = contentElement.innerHTML + xmlhttp.responseText;\n\
         updateTimestamp();\n\
         setTimeout(refresh, refreshDelay);\n\
         } else {\n\
         footerElement.innerHTML = \"<span class=\\\"error\\\">Connection failed! Reload page to try again.</span>\";\n\
         }\n\
         }\n\
         }\n\
         xmlhttp.open(\"GET\", \"/log?after=\" + maxTime, true);\n\
         xmlhttp.send();\n\
         }\n\
         window.onload = function() {\n\
         footerElement = document.getElementById(\"footer\");\n\
         updateTimestamp();\n\
         setTimeout(refresh, refreshDelay);\n\
         }\n\
         </script>", kMinRefreshDelay];
        [string appendString:@"</head>"];
        [string appendString:@"<body>"];
        [string appendString:@"<table><tbody id=\"content\">"];
        [string appendString:htmlContent];
        //[self _appendLogRecordsToString:string afterAbsoluteTime:0.0];
        
        [string appendString:@"</tbody></table>"];
        [string appendString:@"<div id=\"footer\"></div>"];
        [string appendString:@"</body>"];
        [string appendString:@"</html>"];
        
        
    }
//    else if ([path isEqualToString:@"/log"] && query[@"after"]) {
//        string = [[NSMutableString alloc] init];
//        double time = [query[@"after"] doubleValue];
//        [self _appendLogRecordsToString:string afterAbsoluteTime:time];
//
//    }
    else {
        string = [@" <html><body><p>无数据</p></body></html>" mutableCopy];
    }
    if (string == nil) {
        string = [@"" mutableCopy];
    }
    response = [GCDWebServerDataResponse responseWithHTML:string];
    return response;
}

- (NSString*)logHtmlContent{
    NSString* path = @"";//[SQLog getLogFilePath];
    NSMutableString* string = [[NSMutableString alloc] init];
    if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
        NSString* content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
        NSArray<NSString*>* allMsg = [content componentsSeparatedByString:@"\n"];
        __block double maxTime = 0;
        [allMsg enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            const char* style = "color: dimgray;";
            NSString* line = [NSString stringWithFormat:@"<tr style=\"%s\"><div>%@</div></tr>", style, obj];
            [string appendString:line];
        }];
        NSString* line = [NSString stringWithFormat:@"<tr id=\"maxTime\" data-value=\"%f\"></tr>", maxTime];
        [string appendString:line];
    }
    return string;
}

@end
